package com.mzj.saas.mservice.token.service;

import com.alibaba.fastjson.JSON;
import com.mzj.saas.commons.*;
import com.mzj.saas.commons.vo.redis.TokenRedisVo;
import com.mzj.saas.mservice.token.vo.TokenVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
public class TokenService {
	private Logger LOG = LoggerFactory.getLogger(TokenService.class);
	@Value(value = "${token.auth.secretKey}")
	private String tokenAuthSecretKey;// 秘钥
	@Value(value = "${redis.token.expire.time}")
	private Integer redisTokenExpireTime;// 过期时间

	@Autowired
	@Qualifier("stringRedisTemplate")
	public StringRedisTemplate redisTemplate;

	@SuppressWarnings("static-access")
	public ResultBean<String> authToken(TokenVo vo) {
		LOG.info("TokenService authToken parmas = {}", vo.toString());
		ResultBean<String> resultBean = new ResultBean<>();
		try {
			resultBean.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
			resultBean.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());

			if (StringUtils.isBlank(vo.getCode()) || StringUtils.isBlank(vo.getEncryptCode())
					|| StringUtils.isBlank(vo.getIvParameter())) {
				resultBean.setCode(StatusCode.ERROR_CODE_10004.getErrorCode());
				resultBean.setMsg(StatusCode.ERROR_CODE_10004.getErrorMsg());
				return resultBean;
			}

			AESUtil aesUtil = AESUtil.getInstance(tokenAuthSecretKey);
			String decryptCode = aesUtil.aesDecrypt(vo.getEncryptCode(), vo.getIvParameter()); // 校验加密字符串是否合法
			if (!StringUtils.equals(vo.getCode(), decryptCode)) {
				resultBean.setMsg(StatusCode.ERROR_CODE_10003.getErrorMsg());
				resultBean.setCode(StatusCode.ERROR_CODE_10003.getErrorCode());
				return resultBean;
			}

			String md5Code = MD5Utils.MD5Encode(vo.getEncryptCode(), "UTF-8"); // 进行一次md5算法，去除特殊符号
			String tokenKeyValue = Constant.LOGIN_TOKEN + ":" + md5Code;
			if (redisTemplate.opsForValue().get(tokenKeyValue) == null) { // 如果为空的时候,插入redis数据库
				redisTemplate.opsForValue().set(tokenKeyValue, tokenKeyValue, redisTokenExpireTime, TimeUnit.MINUTES);
				LOG.info("TokenService authToken redis save success, key = {}, value = {}", tokenKeyValue,
						tokenKeyValue);
			}

			resultBean.setResultData(redisTemplate.opsForValue().get(tokenKeyValue));
			return resultBean;

		} catch (Exception e) {
			LOG.error("TokenService authToken Exception = {}", e);
			resultBean.setCode(StatusCode.ERROR_CODE_30001.getErrorCode());
			resultBean.setMsg(StatusCode.ERROR_CODE_30001.getErrorMsg());
			return resultBean;
		}

	}

	/**
	 * 生成token
	 *
	 * @param name
	 * @param password
	 * @param id
	 * @param mobile
	 * @param flag
	 * @param masterStatus
	 * @param enterpriseId
	 * @param loginType
	 * @return
	 * @author shun
	 * @date 2021年6月24日
	 */
	public String authToken(String name, String password, String id, String mobile, Integer flag, Long masterStatus,
							Long enterpriseId, Integer loginType, String enterpriseUserId) {
		LOG.info("TokenService authToken name={}, password={}, userId={}, mobile={}, loginType={}, enterpriseUserId={}",
				name, password, id, mobile, loginType, enterpriseUserId);
		try {
			TokenRedisVo vo = new TokenRedisVo();
			vo.setCreateTime(DateUtils.format(new Date(), DateUtils.FORMAT_14));
			vo.setLoginName(mobile);
			vo.setPassword(password);
			vo.setId(id);
			vo.setName(name);
			vo.setFlag(flag);
			vo.setMasterStatus(masterStatus);
			vo.setEnterpriseId(enterpriseId);
			vo.setLoginType(loginType);
			vo.setEnterpriseUserId(enterpriseUserId);
			vo.setPhone(mobile);
			String tokenKey = vo.getLoginName() + vo.getPassword() + vo.getCreateTime() + vo.getName() + vo.getId()
					+ vo.getFlag() + vo.getMasterStatus() + vo.getEnterpriseId() + vo.getPhone();
			String md5tokenKey = Constant.LOGIN_TOKEN + ":" + MD5Utils.MD5Encode(tokenKey, "UTF-8"); // 进行一次md5算法，去除特殊符号
			redisTemplate.opsForValue().set(md5tokenKey, JSON.toJSONString(vo), redisTokenExpireTime, TimeUnit.MINUTES);

			// 缓存用户与token关系
			if(enterpriseId != null){
				redisTemplate.opsForValue().set(Constant.LOGIN_USER + ":" + id + ":" + flag, md5tokenKey);
			}
			return md5tokenKey;

		} catch (Exception e) {
			LOG.error("TokenService authToken Exception = {}", e);

		}
		return null;
	}
	/**
	 * 生成token
	 *
	 * @param name
	 * @param password
	 * @param id
	 * @param mobile
	 * @param flag
	 * @param masterStatus
	 * @param enterpriseId
	 * @param loginType
	 * @return
	 * @author shun
	 * @date 2021年6月24日
	 */
	public String authToken(String name, String password, String id, String mobile, Integer flag, Long masterStatus,
							Long enterpriseId, Integer loginType, String enterpriseUserId,Integer certificationStatus) {
		LOG.info("TokenService authToken name={}, password={}, userId={}, mobile={}, loginType={}, enterpriseUserId={},certificationStatus={}",
				name, password, id, mobile, loginType, enterpriseUserId,certificationStatus);
		try {
			TokenRedisVo vo = new TokenRedisVo();
			vo.setCreateTime(DateUtils.format(new Date(), DateUtils.FORMAT_14));
			vo.setLoginName(mobile);
			vo.setPassword(password);
			vo.setId(id);
			vo.setName(name);
			vo.setFlag(flag);
			vo.setMasterStatus(masterStatus);
			vo.setEnterpriseId(enterpriseId);
			vo.setLoginType(loginType);
			vo.setEnterpriseUserId(enterpriseUserId);
			vo.setCertificationStatus(certificationStatus);
			vo.setPhone(mobile);
			LOG.info("vo = "+JSON.toJSONString(vo));
			String tokenKey = vo.getLoginName() + vo.getPassword() + vo.getCreateTime() + vo.getName() + vo.getId()
					+ vo.getFlag() + vo.getMasterStatus() + vo.getEnterpriseId() + vo.getCertificationStatus() + vo.getPhone();
			String md5tokenKey = Constant.LOGIN_TOKEN + ":" + MD5Utils.MD5Encode(tokenKey, "UTF-8"); // 进行一次md5算法，去除特殊符号
			redisTemplate.opsForValue().set(md5tokenKey, JSON.toJSONString(vo), redisTokenExpireTime, TimeUnit.MINUTES);
			// 缓存用户与token关系
			if(enterpriseId != null){
				redisTemplate.opsForValue().set(Constant.LOGIN_USER + ":" + id + ":" + flag, md5tokenKey);
			}
			return md5tokenKey;

		} catch (Exception e) {
			LOG.error("TokenService authToken Exception = {}", e);

		}
		return null;
	}
	/**
	 * 生成小程序token
	 *
	 * @param name
	 * @param password
	 * @param id
	 * @param mobile
	 * @param flag
	 * @param masterStatus
	 * @param enterpriseId
	 * @param loginType
	 * @return
	 * @author shun
	 * @date 2021年6月24日
	 */
	public String authTokenLet(String name, String password, String id, String mobile, Integer flag, Long masterStatus,
							   Long enterpriseId, Integer loginType, String enterpriseUserId,Integer certificationStatus) {
		LOG.info("TokenService authToken name={}, password={}, userId={}, mobile={}, loginType={}, enterpriseUserId={}",
				name, password, id, mobile, loginType, enterpriseUserId);
		try {
			TokenRedisVo vo = new TokenRedisVo();
			vo.setCreateTime(DateUtils.format(new Date(), DateUtils.FORMAT_14));
			vo.setLoginName(mobile);
			vo.setPassword(password);
			vo.setId(id);
			vo.setName(name);
			vo.setFlag(flag);
			vo.setMasterStatus(masterStatus);
			vo.setEnterpriseId(enterpriseId);
			vo.setLoginType(loginType);
			vo.setEnterpriseUserId(enterpriseUserId);
			vo.setCertificationStatus(certificationStatus);
			String tokenKey = vo.getLoginName() + vo.getPassword() + vo.getCreateTime() + vo.getName() + vo.getId()
					+ vo.getFlag() + vo.getMasterStatus() + vo.getEnterpriseId() + vo.getCertificationStatus();
			String md5tokenKey = Constant.LOGIN_TOKEN + ":" + MD5Utils.MD5Encode(tokenKey, "UTF-8"); // 进行一次md5算法，去除特殊符号
			redisTemplate.opsForValue().set(md5tokenKey, JSON.toJSONString(vo), redisTokenExpireTime, TimeUnit.MINUTES);

			// 缓存用户与token关系
			if(enterpriseId != null){
				redisTemplate.opsForValue().set(Constant.LOGIN_USER + ":" + id + ":" + flag, md5tokenKey);
			}
			return md5tokenKey;

		} catch (Exception e) {
			LOG.error("TokenService authToken Exception = {}", e);

		}
		return null;
	}
	/**
	 * 更新缓存token
	 * @param accessToken
	 * @param vo
	 * @author shun
	 * @date 2021年6月24日
	 */
	public void updateAuthTokenInfo(String accessToken, TokenRedisVo vo){
		redisTemplate.opsForValue().set(accessToken, JSON.toJSONString(vo), redisTokenExpireTime, TimeUnit.MINUTES);
	}
}

